{
 "metadata": {
  "name": ""
 },
 "nbformat": 3,
 "nbformat_minor": 0,
 "worksheets": [
  {
   "cells": [
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Pr\u00e0ctiques de Nous Usos de la Inform\u00e0tica"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "#### Requeriments per fer les pr\u00e0ctiques:"
     ]
    },
    {
     "cell_type": "raw",
     "metadata": {},
     "source": [
      "1) Una forma simple d'instal\u00b7lar tots els paquets necessaris \u00e9s instal\u00b7lar la plataforma de distribuci\u00f3 de Python Anaconda: https://store.continuum.io/\n",
      "Aquesta plataforma instal\u00b7la autom\u00e0ticament un conjunt d'eines (matplotlib, NumPy, SciPy, NetworkX, iPython, pandas, etc.) que constitueixen l'entorn de computaci\u00f3 cient\u00edfica necessari per desenvolupar les pr\u00e0ctiques d'aquesta assignatura. L'altra opci\u00f3 \u00e9s instal\u00b7lar independentment els paquets matplotlib, NumPy, SciPy, NetworkX, iPython i pandas.\n",
      "2) Les pr\u00e0ctiques es poden lliurar en forma de \"notebook\" de iPython que contingui tot el programari desenvolupat per l'alumne o simplement en un m\u00f2dul de Python que contingui tot el programari necessari per executar la pr\u00e0ctica. Informaci\u00f3 sobre iPython: http://ipython.org/"
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b>ENTREGA: </b>\n",
      "El dia l\u00edmit per a l'entrega d'aquesta pr\u00e0ctica \u00e9s el dia <b>18 d'Octubre a les 23.55h</b>\n",
      "\n",
      "<b>Format de l'entrega</b>\n",
      "L'entrega s'efectur\u00e0 mitjan\u00e7ant el campus virtual. S'ha de penjar un arxiu per grup. El nom del fitxer ha de seguir el seg\u00fcent patro:\n",
      "NUI_1_PrimeralletranomCognomMembre1_PrimeralletranomCognomMembre2.iypnb\n",
      "\n",
      "Exemple: <br>\n",
      "Membre 1: Maria del Carme Vil\u00e0<br>\n",
      "Membre 2: Francesc Castell<br>\n",
      "\n",
      "Nom de l'arxiu: <b>NUI_1_MVila_FCastell.ipynb</b>\n",
      "\n"
     ]
    },
    {
     "cell_type": "heading",
     "level": 1,
     "metadata": {},
     "source": [
      "Pr\u00e0ctica 1. Recomanadors"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import pandas as pd\n",
      "unames = ['user_id', 'gender', 'age', 'occupation', 'zip']\n",
      "users = pd.read_table('users.dat', sep='::', header=None, names=unames)\n",
      "rnames = ['user_id', 'movie_id', 'rating', 'timestamp']\n",
      "ratings = pd.read_table('ratings.dat', sep='::', header=None, names=rnames)\n",
      "mnames = ['movie_id', 'title', 'genres']\n",
      "movies = pd.read_table('movies.dat', sep='::', header=None, names=mnames)\n",
      "\n",
      "# Set up a single DataFrame containing all the data to make processing simpler\n",
      "data = pd.merge(pd.merge(ratings, users), movies)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 1
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b> EXERCICI 1:</b>\n",
      "Calcula la puntuaci\u00f3 mitjana de cada usuari. Quina \u00e9s la pel\u00b7l\u00edcula m\u00e9s ben puntuada? "
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# MEAN RATING \n",
      "mean_rating_by_user = data.groupby('user_id')['rating'].mean()\n",
      "print mean_rating_by_user.order(ascending=False)[:2]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "user_id\n",
        "283        4.962963\n",
        "2339       4.956522\n",
        "Name: rating, dtype: float64\n"
       ]
      }
     ],
     "prompt_number": 4
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "user_mean_rating = data.groupby('user_id')['rating'].mean()\n",
      "best_rating_film = data.groupby('title')['rating'].mean()\n",
      "print user_mean_rating.order(ascending=False)[:5], \"\\n\"\n",
      "print best_rating_film.order(ascending=False)[:5]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "user_id\n",
        "283        4.962963\n",
        "2339       4.956522\n",
        "3324       4.904762\n",
        "3902       4.890909\n",
        "446        4.843137\n",
        "Name: rating, dtype: float64 \n",
        "\n",
        "title\n",
        "Ulysses (Ulisse) (1954)                      5\n",
        "Song of Freedom (1936)                       5\n",
        "Smashing Time (1967)                         5\n",
        "Schlafes Bruder (Brother of Sleep) (1995)    5\n",
        "One Little Indian (1973)                     5\n",
        "Name: rating, dtype: float64\n"
       ]
      }
     ],
     "prompt_number": 28
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b>EXERCICI 2:</b> Defineix una funci\u00f3 anomenada <b>top_movie</b> que donat un usuari ens retorni quina \u00e9s la pel\u00b7l\u00edcula millor puntuada.<br> \n",
      "def top_movie(user)\n"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def top_movie(dataFrame,usr):\n",
      "    # agafem un dataframe amb les dades del usr\n",
      "    rated_by_user = dataFrame[dataFrame.user_id == usr]\n",
      "    \n",
      "    # Agafem la pel\u00b7l\u00edcula amb puntuaci\u00f3 m\u00e0xima\n",
      "    return rated_by_user.ix[rated_by_user[\"rating\"].idxmax()]\n",
      "\n",
      "print top_movie(data,1)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "user_id                                            1\n",
        "movie_id                                        1193\n",
        "rating                                             5\n",
        "timestamp                                  978300760\n",
        "gender                                             F\n",
        "age                                                1\n",
        "occupation                                        10\n",
        "zip                                            48067\n",
        "title         One Flew Over the Cuckoo's Nest (1975)\n",
        "genres                                         Drama\n",
        "Name: 0, dtype: object\n"
       ]
      }
     ],
     "prompt_number": 46
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "user = 1\n",
      "best_rated_film_by_user = data[data.user_id == user]\n",
      "best_rated_film_by_user.sort(columns='rating',ascending=False)\n",
      "best_rated_film_by_user[:1]"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "html": [
        "<div style=\"max-height:1000px;max-width:1500px;overflow:auto;\">\n",
        "<table border=\"1\" class=\"dataframe\">\n",
        "  <thead>\n",
        "    <tr style=\"text-align: right;\">\n",
        "      <th></th>\n",
        "      <th>user_id</th>\n",
        "      <th>movie_id</th>\n",
        "      <th>rating</th>\n",
        "      <th>timestamp</th>\n",
        "      <th>gender</th>\n",
        "      <th>age</th>\n",
        "      <th>occupation</th>\n",
        "      <th>zip</th>\n",
        "      <th>title</th>\n",
        "      <th>genres</th>\n",
        "    </tr>\n",
        "  </thead>\n",
        "  <tbody>\n",
        "    <tr>\n",
        "      <th>0</th>\n",
        "      <td> 1</td>\n",
        "      <td> 1193</td>\n",
        "      <td> 5</td>\n",
        "      <td> 978300760</td>\n",
        "      <td> F</td>\n",
        "      <td> 1</td>\n",
        "      <td> 10</td>\n",
        "      <td> 48067</td>\n",
        "      <td> One Flew Over the Cuckoo's Nest (1975)</td>\n",
        "      <td> Drama</td>\n",
        "    </tr>\n",
        "  </tbody>\n",
        "</table>\n",
        "</div>"
       ],
       "metadata": {},
       "output_type": "pyout",
       "prompt_number": 54,
       "text": [
        "   user_id  movie_id  rating  timestamp gender  age  occupation    zip  \\\n",
        "0        1      1193       5  978300760      F    1          10  48067   \n",
        "\n",
        "                                    title genres  \n",
        "0  One Flew Over the Cuckoo's Nest (1975)  Drama  "
       ]
      }
     ],
     "prompt_number": 54
    },
    {
     "cell_type": "heading",
     "level": 3,
     "metadata": {},
     "source": [
      "1.2 Construcci\u00f3 d'un recomanador."
     ]
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b>Exercici 3: </b>\n",
      "\n",
      "Construeix dues funcions, <b>distEuclid(x,y)</b> i <b>coefPearson(x,y)</b>, que implementin la dist\u00e0ncia Euclidiana i el coeficient de correlaci\u00f3 de Pearson entre dos vectors. Escriu les funcions que calculin la semblan\u00e7a entre dos usuaris segons aquesta estructura:\n",
      "\n",
      "<b>def SimEuclid (DataFrame, User1, User2)</b>\n",
      "    Calcular els vectors representatius de cada usuari, C1 i C2, amb les puntuacions dels \u00edtems comuns que han puntuat el dos usuaris.<br>\n",
      "    Si no hi ha puntuacions en com\u00fa, retornar 0.\n",
      "    Retornar 1/(1+distEuclid(C1, C2))<br>\n",
      "    \n",
      "<b>def SimPearson (DataFrame, User1, User2)</b>\n",
      "    Calcular els vectors representatius de cada usuari, C1 i C2, amb les puntuacions dels \u00edtems comuns que han puntuat el dos usuaris.<br>\n",
      "    Si no hi ha puntuacions en com\u00fa, retornar 0.>\n",
      "    Retornar coefPearson(C1,C2)<br>\n",
      "    \n",
      "\n",
      "<b>Utilizeu el panda per a realitzaci\u00f3 d'aquest exercici.</b>"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "import math\n",
      "import numpy as np\n",
      "import pandas as pd\n",
      "\n",
      "def average(x):\n",
      "    assert len(x) > 0\n",
      "    return float(sum(x)) / len(x)\n",
      "\n",
      "\n",
      "def distEuclid(x, y):\n",
      "    sum_of_squares=float(math.sqrt(sum(pow((x-y),2))))\n",
      "    return 1.0/(1.0+sum_of_squares)\n",
      "  \n",
      "def coefPearson(x, y):\n",
      "    assert len(x) == len(y)\n",
      "    n = len(x)\n",
      "    if n>0:\n",
      "        avg_x = average(x)\n",
      "        avg_y = average(y)\n",
      "        diffprod = 0\n",
      "        xdiff2 = 0\n",
      "        ydiff2 = 0\n",
      "        for idx in range(n):\n",
      "            xdiff = x[idx] - avg_x\n",
      "            ydiff = y[idx] - avg_y\n",
      "            diffprod += xdiff * ydiff\n",
      "            xdiff2 += xdiff * xdiff\n",
      "            ydiff2 += ydiff * ydiff\n",
      "        if (math.sqrt(xdiff2 * ydiff2)==0):\n",
      "            return 0\n",
      "        return diffprod / math.sqrt(xdiff2 * ydiff2)\n",
      "    else:\n",
      "        return 0\n",
      "\n",
      "# Returns a distance-based similarity score for person1 and person2\n",
      "def SimEuclid(DataFrame,User1,User2):\n",
      "    # GET MOVIES OF USER1\n",
      "    movies_user1=DataFrame[DataFrame['user_id'] ==User1 ]\n",
      "    # GET MOVIES OF USER2\n",
      "    movies_user2=DataFrame[DataFrame['user_id'] ==User2 ]\n",
      "    # FIND SHARED FILMS\n",
      "    rep=pd.merge(movies_user1 ,movies_user2,on='movie_id')    \n",
      "    if len(rep)==0:\n",
      "        return 0\n",
      "    return distEuclid(rep['rating_x'],rep['rating_y']) \n",
      "\n",
      "def SimPearson(DataFrame,User1,User2):\n",
      "    # GET MOVIES OF USER1\n",
      "    movies_user1=DataFrame[DataFrame['user_id'] ==User1 ]\n",
      "    # GET MOVIES OF USER2\n",
      "    movies_user2=DataFrame[DataFrame['user_id'] ==User2 ]\n",
      "    # FIND SHARED FILMS\n",
      "    rep=pd.merge(movies_user1 ,movies_user2,on='movie_id')\n",
      "    if len(rep)==0:\n",
      "        return 0    \n",
      "    return coefPearson(rep['rating_x'],rep['rating_y'])"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 13
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# Execute functions\n",
      "print SimEuclid(data,1,6040)\n",
      "print SimPearson(data,1,2)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "   user_id_x  movie_id  rating_x  timestamp_x gender_x  age_x  occupation_x  \\\n",
        "0          1      1193         5    978300760        F      1            10   \n",
        "1          1       919         4    978301368        F      1            10   \n",
        "2          1      2791         4    978302188        F      1            10   \n",
        "3          1       720         3    978300760        F      1            10   \n",
        "4          1      1270         5    978300055        F      1            10   \n",
        "\n",
        "   zip_x                                            title_x  \\\n",
        "0  48067             One Flew Over the Cuckoo's Nest (1975)   \n",
        "1  48067                           Wizard of Oz, The (1939)   \n",
        "2  48067                                   Airplane! (1980)   \n",
        "3  48067  Wallace & Gromit: The Best of Aardman Animatio...   \n",
        "4  48067                          Back to the Future (1985)   \n",
        "\n",
        "                             genres_x  user_id_y  rating_y  timestamp_y  \\\n",
        "0                               Drama       6040         4    957716612   \n",
        "1  Adventure|Children's|Drama|Musical       6040         5    956704191   \n",
        "2                              Comedy       6040         4    956715569   \n",
        "3                           Animation       6040         4    957717191   \n",
        "4                       Comedy|Sci-Fi       6040         3    997453960   \n",
        "\n",
        "  gender_y  age_y  occupation_y  zip_y  \\\n",
        "0        M     25             6  11106   \n",
        "1        M     25             6  11106   \n",
        "2        M     25             6  11106   \n",
        "3        M     25             6  11106   \n",
        "4        M     25             6  11106   \n",
        "\n",
        "                                             title_y  \\\n",
        "0             One Flew Over the Cuckoo's Nest (1975)   \n",
        "1                           Wizard of Oz, The (1939)   \n",
        "2                                   Airplane! (1980)   \n",
        "3  Wallace & Gromit: The Best of Aardman Animatio...   \n",
        "4                          Back to the Future (1985)   \n",
        "\n",
        "                             genres_y  \n",
        "0                               Drama  \n",
        "1  Adventure|Children's|Drama|Musical  \n",
        "2                              Comedy  \n",
        "3                           Animation  \n",
        "4                       Comedy|Sci-Fi  \n",
        "0.190743569831\n",
        "0.416666666667\n"
       ]
      }
     ],
     "prompt_number": 12
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b>Exercici 4:</b>\n",
      "\n",
      "Feu dues funcions, <b>getNBestEuclid(DataFrame, user,n)</b> i <b>getNBestPearson(DataFrame, user,n)</b>, que retornin els n usuaris m\u00e9s semblants segons aquestes dues mesures de similitud."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# return the N most similar users to the given user based on the given similarity metric\n",
      "def getNBest(DataFrame,user,n,similarity):\n",
      "    users = list(set(DataFrame.user_id)) # Get all unique users as an iterable list\n",
      "    #merge with user films to speed up the process working with a reduced set\n",
      "    user_films = pd.DataFrame({'movie_id' : list(set(DataFrame[DataFrame.user_id == user]['movie_id']))})\n",
      "    data_frame = DataFrame.merge(user_films, how = \"inner\") # overwrite data set with the reduced one\n",
      "    return sorted([ (similarity(data_frame,user,x),x) for x in users if x != user ],reverse=True)[:n]\n",
      "    \n",
      "# return the N most similar users to given user based on euclidean distance\n",
      "def getNBestEuclid(DataFrame,user,n):    \n",
      "    return getNBest(DataFrame,user,n,SimEuclid)\n",
      "\n",
      "# return the N most similar users to given user based on pearson distance\n",
      "def getNBestPearson(DataFrame,user,n):\n",
      "    return getNBest(DataFrame,user,n,SimPearson)\n"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 188
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# EXECUTE FUNCTIONS\n",
      "print getNBestEuclid(data,1,10)\n",
      "print getNBestPearson(data,1,10)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "[(1.0, 6033), (1.0, 6012), (1.0, 5932), (1.0, 5910), (1.0, 5817), (1.0, 5781), (1.0, 5713), (1.0, 5590), (1.0, 5577), (1.0, 5503)]\n",
        "[(1.0, 6033), (1.0, 5940), (1.0, 5919), (1.0, 5910), (1.0, 5856), (1.0, 5672), (1.0, 5590), (1.0, 5546), (1.0, 5476), (1.0, 5436)]"
       ]
      },
      {
       "output_type": "stream",
       "stream": "stdout",
       "text": [
        "\n"
       ]
      }
     ],
     "prompt_number": 189
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b>Exercici 5:</b>\n",
      "\n",
      "Desenvolupa un sistema de recomanaci\u00f3 col\u00b7laboratiu basat en usuaris. La funci\u00f3 principal, <b>getRecommendationsUser</b>, ha de tenir com a entrada una taula de puntuacions, un \"user_id\", el tipus de mesura de semblan\u00e7a (Euclidiana o Pearson) que volem usar i el nombre n m\u00e0xim de recomanacions que volem. Com a sortida ha de donar la llista de les 5 millors pel\u00b7l\u00edcules que li podriem recomanar segons la seva semblan\u00e7a amb altres usuaris.\n",
      "\n",
      "Nota: S'ha d'evitar comparar \"user_id\" a ell mateix."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# Gets recommendations for a person by using a weighted average\n",
      "# of every other user's rankings\n",
      "def getRecommendationsUser(DataFrame,person,n,similarity=SimPearson):\n",
      "    totals={}\n",
      "    simSums={}\n",
      "    # users in database\n",
      "    movies_user1=DataFrame[DataFrame['user_id'] ==person]\n",
      "    \n",
      "    allUsers=set(DataFrame['user_id'])\n",
      "    for other in allUsers:\n",
      "        # no es comparem am nosalres mateixos\n",
      "        if other==person: continue\n",
      "        # Agafem la similitud entre els usuaris\n",
      "        sim=similarity(DataFrame,person,other)\n",
      "        \n",
      "        if sim<=0: continue\n",
      "        # ignore scores of zero or lower\n",
      "        movies_user2=DataFrame[DataFrame['user_id'] ==other ]\n",
      "        films=pd.merge(movies_user1[['movie_id','rating']] ,movies_user2[['movie_id','rating']],on='movie_id',how='inner') \n",
      "        for item in films.index:\n",
      "            # Similarity * Score\n",
      "            totals.setdefault(item,0)\n",
      "            totals[item]+=films.ix[item]['rating_y']*sim\n",
      "            # Sum of similarities\n",
      "            simSums.setdefault(item,0)\n",
      "            simSums[item]+=sim\n",
      "            \n",
      "    # Create the normalized list\n",
      "    rankings=[(total/simSums[item],item) for item,total in totals.items()]\n",
      "    # Return the sorted list\n",
      "    rankings.sort()\n",
      "    rankings.reverse()\n",
      "    return rankings[0:n]\n",
      "\n",
      "\n",
      "getRecommendationsUser(data, 2, 10,SimEuclid)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 15
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b>Exercici 6:</b>\n",
      "\n",
      "Desenvolupa un sistema de recomanaci\u00f3 col\u00b7laboratiu basat en \u00edtems. \n",
      "\n",
      "Primer, escriu una funci\u00f3 <b>CalcSimItems(DataFrame)</b>, que construeixi i retorni una taula, itemsim, amb les semblances entre els \u00edtems.\n",
      "Despr\u00e9s escriu la funci\u00f3 principal, <b>getRecommendationsItem(DataFrame, itemsim, user, n)</b>, ha de tenir com a entrada les puntuacions dels usuaris, la taula de semblan\u00e7a entre \u00edtems, un \"user_id\" i el nombre n m\u00e0xim de recomanacions que volem. Com a sortida ha de donar les n millors pel\u00b7l\u00edcules."
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "# Returns a distance-based similarity score for person1 and person2\n",
      "def SimEuclidItems(DataFrame,Movie1,Movie2):\n",
      "    # GET USERS OF MOVIE1\n",
      "    movies_user1=DataFrame[DataFrame['movie_id'] ==Movie1 ]\n",
      "    # GET USERS OF MOVIE2\n",
      "    movies_user2=DataFrame[DataFrame['movie_id'] ==Movie2 ]\n",
      "    # FIND SHARED FILMS\n",
      "    rep=pd.merge(movies_user1 ,movies_user2,on='user_id')  \n",
      "    if len(rep)==0:\n",
      "        return 0\n",
      "    return distEuclid(rep['rating_x'],rep['rating_y']) \n",
      "\n",
      "def SimPearsonItems(DataFrame,Movie1,Movie2):\n",
      "    # GET USERS OF MOVIE1\n",
      "    movies_user1=DataFrame[DataFrame['movie_id'] ==Movie1 ]\n",
      "    # GET USERS OF MOVIE2\n",
      "    movies_user2=DataFrame[DataFrame['movie_id'] ==Movie2 ]\n",
      "    # FIND SHARED FILMS\n",
      "    rep=pd.merge(movies_user1 ,movies_user2,on='user_id')\n",
      "    if len(rep)==0:\n",
      "        return 0    \n",
      "    return coefPearson(rep['rating_x'],rep['rating_y']) \n",
      "\n",
      "# Compute the similarity matrix of movies\n",
      "def CalcSimItems(DataFrame, similarity = SimPearsonItems):\n",
      "    # llistat de pelis\n",
      "    movie_ids = list(set(DataFrame['movie_id']))\n",
      "    # Creem un dataframe\n",
      "    itemsim = pd.DataFrame(index = movie_ids)\n",
      "    itemsim.columns.name = 'movie_id'\n",
      "    # per a cada pel\u00b7l\u00edcula calculem la similitud amb la resta\n",
      "    for movie_id_1 in movie_ids:\n",
      "        # calculamos las distancias\n",
      "        distancies = [ similarity(DataFrame,movie_id_1,movie_id_2) for movie_id_2 in movie_ids ]\n",
      "        itemsim[movie_id_1] = distancies   \n",
      "    return itemsim\n",
      "    \n",
      "# Get the recomendataions based on items\n",
      "def getRecommendationsItem(DataFrame, itemsim, user, n):\n",
      "    \n",
      "    #: listado con items unicos\n",
      "    movie_ids = list(set(DataFrame['movie_id']))\n",
      "    #items del user\n",
      "    user_items =  list(set(DataFrame[DataFrame['user_id'] == user]['movie_id']))\n",
      "    #agafem el conjunt de pelis que l'usuari no ha vist\n",
      "    movies_not_seen = [ x for x in movie_ids if x not in user_items ]\n",
      "    \n",
      "    # dataframe amb els rating\n",
      "    ratings = DataFrame[DataFrame['user_id'] == user][['movie_id','rating']]\n",
      "    ratings.index = ratings.movie_id.values\n",
      "    # llista pel\u00b7l\u00edcules vistes\n",
      "    seen_movies = list(set(DataFrame[DataFrame['user_id'] == user]['movie_id']))\n",
      "    results = []\n",
      "    # recorrem les pel\u00b7l\u00edcules no vistes i obtenim el seu score\n",
      "    for movie in movies_not_seen:\n",
      "        sum_sim = 0\n",
      "        x_simil = 0\n",
      "        # itarem per les pel\u00b7l\u00edcules que hem vist\n",
      "        for item in seen_movies:\n",
      "            sum_sim += itemsim[movie][item]\n",
      "            x_simil += ( itemsim.ix[movie][item] * ratings.ix[item]['rating'] )\n",
      "        # normalitzacio\n",
      "        results.append(x_simil / sum_sim)\n",
      "    # creamos dataframe de salida\n",
      "    df = pd.DataFrame(data = {'movie_id':  movies_not_seen, 'score':results })\n",
      "    return sorted([(df.ix[item]['score'],df.ix[item]['movie_id']) for item in df.index ],reverse=True)[:n]\n",
      "    \n",
      "itemsim = CalcSimItems(data[:90000])\n",
      "result=getRecommendationsItem(data[:90000], itemsim, 2, 10)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 266
    },
    {
     "cell_type": "markdown",
     "metadata": {},
     "source": [
      "<b>Exercici 7:</b> Creu una funcio, <b>evaluateRecommendationsUser(DataFrame,DataFrameTest,similarity=SimPearson)</b>, que donat un conjunt de dades d'entrenament i un conjunt de dades de test ens avalua la precisi\u00f3 dels sistema.\n",
      "Per a cadascun dels elements del conjunt de test haurem de pronosticar el seu valor i comparar-lo amb el valor real que l'usuari li ha asignat.\n"
     ]
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "def EvaluateRecommendationsUser(DataFrame,DataFrameTest,similarity=SimPearson):\n",
      "    scores = []\n",
      "    for index in DataFrameTest.index:            \n",
      "        user  = DataFrameTest.ix[index][\"user_id\"]\n",
      "        movie = DataFrameTest.ix[index][\"movie_id\"]\n",
      "        score = DataFrameTest.ix[index][\"rating\"]\n",
      "        \n",
      "        df = DataFrame[DataFrame['movie_id'] == movie]\n",
      "        \n",
      "        # Creem una nova columna amb la similitud del usuaris\n",
      "        df[\"similarity\"] = df.apply(lambda x: similarity(DataFrame, user, x[\"user_id\"]), axis=1)\n",
      "                \n",
      "        # Creem una nova columna amb rating poderat per la similitud\n",
      "        df[\"weighted_rating\"] = df[\"rating\"] * df[\"similarity\"]\n",
      "        \n",
      "        # caculmem l'score\n",
      "        results = df.sum()\n",
      "        predicted_score = results[\"weighted_rating\"] / results[\"similarity\"]\n",
      "        \n",
      "        scores.append(abs(score - predicted_score))\n",
      "    \n",
      "    return sum(scores)/len(scores)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 12
    },
    {
     "cell_type": "code",
     "collapsed": false,
     "input": [
      "ratings = EvaluateRecommendationsUser(data[10:100000],data[0:9],similarity=SimEuclid)"
     ],
     "language": "python",
     "metadata": {},
     "outputs": [],
     "prompt_number": 13
    }
   ],
   "metadata": {}
  }
 ]
}